/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package elaborate.tag_analysis.client.ui.model;

import elaborate.tag_analysis.client.ServiceContext;
import elaborate.tag_analysis.client.applications.Application;
import elaborate.tag_analysis.model.Resource;
import elaborate.task.Task;
import elaborate.task.TaskQueue;
import java.awt.Cursor;
import java.util.List;
import java.util.Vector;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

/**
 *
 * @author lendle
 */
public class OndemandResourceTreeModel implements TreeModel {

    private ResourceTreeNode rootNode = new ResourceTreeNode();
    private List<TreeModelListener> listeners = new Vector<TreeModelListener>();
    private ServiceContext serviceContext=null;

    public ServiceContext getServiceContext() {
        return serviceContext;
    }

    public void setServiceContext(ServiceContext serviceContext) {
        this.serviceContext = serviceContext;
    }

    @Override
    public Object getRoot() {
        return rootNode;
    }

    public ResourceTreeNode getRootNode() {
        return rootNode;
    }

    public void setRoot(ResourceTreeNode rootNode) {
        this.rootNode = rootNode;
    }

    @Override
    public Object getChild(Object o, int i) {
        ResourceTreeNode node = (ResourceTreeNode) o;
        //System.out.println("getChild: "+o+":"+node.isCategory());
        loadChildren(node);
        return node.getChildren().get(i);
    }

    private synchronized void loadChildren(final ResourceTreeNode node) {
//        if(1==1){
//            return;
//        }
        if(serviceContext.getActiveApplication()==null){
            return;
        }
        if (!node.isChildrenLoaded() && node.getResource()!=null) {
            node.setChildrenLoaded(true);
            serviceContext.executeTask(new Task() {

                @Override
                public Object run() throws Exception {
                    try{
                        serviceContext.getResourceTree().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                        List<Resource> resources=serviceContext.getActiveApplication().getResourceHandler().loadResources(node.getResource().getId());
                        if(resources!=null){
                            for(Resource resource : resources){
                                node.getChildren().add(new ResourceTreeNode(resource));
                            }
                        }

                        SwingUtilities.invokeLater(new Runnable() {

                            @Override
                            public void run() {
                                serviceContext.getResourceTree().updateUI();
                            }
                        });
                        return null;
                    }finally{
                        serviceContext.getResourceTree().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                    }
                }
            });

        }
    }

    @Override
    public int getChildCount(Object o) {
        //System.out.println("getChildCount");
        ResourceTreeNode node = (ResourceTreeNode) o;
        this.loadChildren(node);
        return node.getChildren().size();
    }

    @Override
    public boolean isLeaf(Object o) {
        ResourceTreeNode node = (ResourceTreeNode) o;
        if (node.isCategory()) {
            return false;
        } else if (node != this.rootNode) {
            return true;
        }
        //System.out.println("isLeaf: "+o+":"+node.isCategory());
        this.loadChildren(node);
        return node.getChildren().isEmpty();
    }

    @Override
    public void valueForPathChanged(TreePath tp, Object o) {
        return;
    }

    @Override
    public int getIndexOfChild(Object o, Object o1) {
        //System.out.println("getIndexOfChild");
        ResourceTreeNode node = (ResourceTreeNode) o;
        this.loadChildren(node);
        int index = 0;
        for (ResourceTreeNode _node : node.getChildren()) {
            if (_node == o1) {
                return index;
            } else {
                index++;
            }
        }
        return -1;
    }

    @Override
    public void addTreeModelListener(TreeModelListener tl) {
        this.listeners.add(tl);
    }

    @Override
    public void removeTreeModelListener(TreeModelListener tl) {
        this.listeners.remove(tl);
    }
}
